using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Web;
using System.Xml;

namespace limpalex.bbparser
{
    public sealed class SmileyConfiguration
    {
        private const string SmileyFormatWithoutClass = "<img src='{0}{1}' alt='{2}' />";
        private const string SmileyFormatWithClass = "<img src='{0}{1}' alt='{2}' class='{3}' title='{2}' />";
        private readonly NameValueCollection _replacements = new NameValueCollection();
        private readonly List<string> _images = new List<string>();
        private string _smileyPath;
        private string _smileyCssClass;

        public void Clear()
        {
            _replacements.Clear();
            _images.Clear();
        }
        
        public void AddSmiley(string text, string image)
        {
            _replacements.Add(text, image);
            if ( !_images.Contains(image))
                _images.Add(image);
        }

        public void AddSmiley(IList<string> text, string image)
        {
            foreach (string s in text)
            {
                AddSmiley(s, image);
            }
        }

        public IEnumerable<string> AllKeys
        {
            get
            {
                foreach (string s in _replacements.AllKeys)
                {
                    yield return s;
                }
            }
        }

        public IEnumerable<string> AllImages
        {
            get
            {
                foreach (string s in _images)
                {
                    yield return s;
                }
            }
        }

        public string SmileyPath
        {
            get { return _smileyPath; }
            set { _smileyPath = value; }
        }

        public string SmileyCssClass
        {
            get { return _smileyCssClass; }
            set { _smileyCssClass = value; }
        }

        public string GetReplacement(string key)
        {
            return _replacements[key];
        }

        public IEnumerable<string> GetKeys(string image)
        {
            foreach (string s in _replacements.AllKeys)
            {
                if ( _replacements[s].Equals(image))
                    yield return s;
            }
        }

        public string ProcessText(string input)
        {
            string working = input;
            foreach (string key in _replacements.AllKeys)
            {
                if (working.IndexOf(key) != -1)
                    working = working.Replace(key, CreateSmiley(key));
            }

            return working;
        }

        private string CreateSmiley(string key)
        {
            if (string.IsNullOrEmpty(_smileyCssClass))
                return string.Format(SmileyFormatWithoutClass, _smileyPath, _replacements[key], HttpUtility.HtmlEncode(key));
            return string.Format(SmileyFormatWithClass, _smileyPath, _replacements[key], HttpUtility.HtmlEncode(key), _smileyCssClass);
        }

        private SmileyConfiguration() {}

        public static SmileyConfiguration Create(XmlNode node)
        {
            var result = new SmileyConfiguration();

            if ( node.Attributes["path"] != null)
            {
                result.SmileyPath = node.Attributes["path"].Value;
            }
            else
            {
                result.SmileyPath = string.Empty;
            }

            if ( node.Attributes["class"] != null )
            {
                result.SmileyCssClass = node.Attributes["class"].Value;
            }
            else
            {
                result.SmileyCssClass = string.Empty;
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if ( child.NodeType != XmlNodeType.Element)
                    continue;
                string image = string.Empty; IList<string> text = null;

                foreach (XmlNode smileyChild in child.ChildNodes)
                {
                    if (smileyChild.NodeType != XmlNodeType.Element)
                        continue;
                    if (smileyChild.Name == "path")
                        image = smileyChild.InnerText;
                    if (smileyChild.Name == "strings")
                    {
                        text = new List<string>();

                        foreach(XmlNode stringNode in smileyChild.ChildNodes)
                        {
                            if (stringNode.NodeType != XmlNodeType.Element)
                                continue;
                            text.Add(stringNode.InnerText);
                        }
                    }
                }

                result.AddSmiley(text, image);
            }

            return result;
        }
    }
}
